#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2020/6/22 14:33
# @Author : wn 
# @File: live.py
# @SoftWare: PyCharm
# @Site:
# @Table:
# ｡◕‿◕｡｡◕‿◕｡｡◕‿◕｡

import json
from operator import itemgetter

from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.views import View

from trade.OperationLog import OperationLog
from trade.model_choices import *
from trade.models import *
from trade.search_page import searchs_live
from utils.chardate import chardate
from utils.service import my_page
import datetime
import time


class Live(View):
    '''
    实盘策略
    '''

    def __init__(self):
        self.title = "实盘列表"
        self.url = '/trade/live'
        self.opt = '提交实盘'

    def get(self, request):
        # 当前访问用户
        customerid = request.GET.get('customerid', None)
        if customerid:
            request.session['customerid'] = customerid
            print('get方式，当前访问的用户是：', customerid)

        # 当前在第几页
        off = request.GET.get('offset', None)
        # 一页几条
        lim = request.GET.get('limit', None)

        if lim is None:
            html = "live.html" if self.url == "/trade/live" else "liveApproval.html"
            return render(request, html, {'url': self.url, 'title': self.title})
        else:
            customerid = request.session.get("customerid", 'noCid')
            tab_type = request.GET.get("type")
            live_approvals = list(Liveapproval.objects.using('quantWebDB').all())
            result_list = []
            for item in live_approvals:
                result_dict = {}
                result_dict['stgid'] = item.stgid
                result_dict['envid'] = item.envid
                result_dict['remark'] = item.remark
                result_dict['audittime'] = item.audittime
                result_dict['inserttime'] = item.inserttime
                result_dict['auditstatus'] = AuditStatus.get(item.auditstatus, None)
                result_dict['auditmsg'] = item.auditmsg
                result_dict['packstatus'] = PackStatus_ModelChoices.get(item.packstatus, None)
                result_dict['packmsg'] = item.packmsg
                result_dict['packtime'] = item.packtime

                # 策略表中的：策略名称，上传时间
                stginfo_list = list(Strategy.objects.using('quantWebDB').filter(stgid=item.stgid))
                if len(stginfo_list) != 0:
                    result_dict['stgname'] = stginfo_list[0].stgname
                    result_dict['createtime'] = stginfo_list[0].createtime
                    result_dict['liveisdelete'] = stginfo_list[0].liveisdelete
                    result_dict['isopr'] = "0"
                    if customerid == stginfo_list[0].customerid:
                        result_dict['isopr'] = "1"

                # 环境表中的：服务器（envname+ip)
                envinfo_list = list(Environment.objects.using('quantWebDB').filter(envid=item.envid))
                if len(envinfo_list) != 0:
                    # result_dict['envname'] = envinfo_list[0].envname + "(" + envinfo_list[0].ip + ")"
                    result_dict['envname'] = envinfo_list[0].envname
                    result_dict['backtype'] = BackType.get(envinfo_list[0].backtype)

                # 实盘运行表
                liverun_list = list(Liverun.objects.using('quantWebDB').filter(stgid=item.stgid))
                if liverun_list is not None and len(liverun_list) != 0:
                    result_dict['starttime'] = liverun_list[0].starttime
                    result_dict['endtime'] = liverun_list[0].endtime
                    result_dict['runstatus'] = StgRunStatus.get(liverun_list[0].runstatus, None)

                # 都打包成功可以显示到实盘列表
                laPS_qs = Liveapproval.objects.using('quantWebDB').filter(stgid=item.stgid)
                flagPackStatus = True
                for laps in laPS_qs:
                    if laps.auditstatus == '3' and laps.packstatus != "1":
                        flagPackStatus = False

                # 操作value
                result_dict['poption'] = str(item.stgid) + "_" + str(item.envid)  # 打包列表
                result_dict['loption'] = item.stgid  # 实盘列表
                if tab_type == "1" and result_dict.get("auditstatus") == "审批通过":
                    result_list.append(result_dict)
                elif tab_type == "2" and result_dict['auditstatus'] == "审批通过" and result_dict[
                    'liveisdelete'] == 1 and result_dict.get("backtype") == '1' and flagPackStatus:
                    result_list.append(result_dict)

            # 排序
            for item in result_list:
                if (item.get('stgid') is None):
                    item['stgid'] = '-1'
            result_list_sorted = sorted(result_list, key=itemgetter('stgid'), reverse=True)
            result = my_page(result_list_sorted, lim, off)
            return JsonResponse(result, safe=False)

    def post(self, request):
        customerid = request.session.get('id', 'noCid')
        # 实盘列表，状态非启动时，只删除页面显示，修改liveisdelete = 0
        if request.POST.get('delete_live_list', None):
            stgid = int(request.POST.get('id'))  # int(str)
            qbnum = str(request.POST.get("qbnum"))
            Strategy.objects.using('quantWebDB').filter(stgid=stgid).update(
                liveisdelete=0,
            )

            # 毫秒级别时间后缀
            time_suffix = str(round(time.time() * 1000))
            qbnum = qbnum + time_suffix

            # 实盘列表删除，修改QB账号，保持QB账号可重复用
            Liveapproval.objects.using('quantWebDB').filter(stgid=stgid).update(remark=qbnum)

            # 操作日志 	删除策略：包括两种，上传策略后的物理删除策略、审批通过后的连接删除，记录删除人员、删除时间、删除策略ID、删除策略名
            stg = Strategy.objects.using('quantWebDB').filter(stgid=stgid)[0]
            stgname = stg.stgname
            customerid_log = request.session.get('id', 'noCid')
            log_dict = {
                'customerid': customerid_log,
                'modular': '1',
                'optfunction': '2',
                'optinfo': '删除策略_页面删除，策略ID：%s，策略名称：%s' % (
                    stgid, stgname),
                'opttime': chardate(),
            }
            OperationLog.opt_log(log_dict)

            jsonRes = searchs_live(stgid_search="", stgname_search="",
                                   stgrunstatus_search="", type='liveList', customerid=customerid)
            return jsonRes
        elif request.POST.get('stg_pack', None):
            stgid_envid = request.POST.get('id')  # str
            se_list = stgid_envid.split('_')
            # 打包，实盘策略审批表打包状态=='0'
            stgid = int(se_list[0])  # int(str)
            Liveapproval.objects.using('quantWebDB').filter(stgid=stgid, envid=se_list[1]).update(
                packstatus='0',
                packmsg='',
            )
            # 操作日志 	手工打包：记录申请打包时间、打包人员、打包结果
            customerid_log = request.session.get('id', 'noCid')
            log_dict = {
                'customerid': customerid_log,
                'modular': '1',
                'optfunction': '3',
                'optinfo': '实盘手工打包，申请人：%s，打包时间：%s，打包结果：%s' % (
                    customerid_log, chardate(), '手工打包成功'),
                'opttime': chardate(),
            }
            OperationLog.opt_log(log_dict)
            jsonRes = searchs_live(stgname_search="", packstatus_search="",
                                   type='livePackList')
            return jsonRes
        elif request.POST.get('stg_pack_error', None):
            stgid_envid = request.POST.get('id')  # str
            se_list = stgid_envid.split('_')
            # 打包，实盘策略审批表打包状态=='0'
            stgid = int(se_list[0])  # int(str)
            packmsg_qs = Liveapproval.objects.using('quantWebDB').filter(stgid=stgid, envid=se_list[1]).values_list(
                'packmsg')  # [('',)('缺少python')] -- [list(('',))][0][0]
            packmsg = ''
            if len(packmsg_qs) != 0:
                packmsg = list(packmsg_qs[0])[0]
            return JsonResponse({'packmsg': packmsg})


class LiveApproval(Live):
    '''
    实盘策略审批
    '''

    def __init__(self):
        super(LiveApproval, self).__init__()
        self.title = '实盘策略审批'
        self.url = '/trade/live_approval'
        self.opt = '实盘策略审批'

    def get(self, request):
        # 当前访问用户
        customerid = request.GET.get('customerid', None)
        if customerid:
            request.session['customerid'] = customerid
            print('get方式，当前访问的用户是：', customerid)

        # 当前在第几页
        off = request.GET.get('offset', None)
        # 一页几条
        lim = request.GET.get('limit', None)

        if lim is None:
            html = "live.html" if self.url == "/trade/live" else "liveApproval.html"
            return render(request, html, {'url': self.url})
        else:
            live_approvals = list(Liveapproval.objects.using('quantWebDB').all())
            live_approvals_filterList = []
            for obj_la in live_approvals:
                envObj_qs = Environment.objects.using('quantWebDB').filter(envid=obj_la.envid)
                if len(envObj_qs) != 0:
                    envObj = envObj_qs[0]
                    # "1":主服务器,"2":被服务器
                    if envObj.backtype == '1':
                        live_approvals_filterList.append(obj_la)

            result_list = []
            # for item in live_approvals:
            for item in live_approvals_filterList:
                result_dict = {}
                result_dict['stgid'] = item.stgid
                result_dict['envid'] = item.envid
                result_dict['remark'] = item.remark
                result_dict['audittime'] = item.audittime
                result_dict['inserttime'] = item.inserttime
                result_dict['auditstatus'] = AuditStatus.get(item.auditstatus, None)
                result_dict['auditmsg'] = item.auditmsg
                result_dict['packstatus'] = item.packstatus
                result_dict['packmsg'] = item.packmsg
                result_dict['packtime'] = item.packtime

                # 策略表中的：策略名称，上传时间
                stginfo_list = list(Strategy.objects.using('quantWebDB').filter(stgid=item.stgid))
                if len(stginfo_list) != 0:
                    result_dict['stgname'] = stginfo_list[0].stgname
                    result_dict['createtime'] = stginfo_list[0].createtime

                # 环境表中的：服务器（envname+ip)
                envinfo_list = list(Environment.objects.using('quantWebDB').filter(envid=item.envid))
                if len(envinfo_list) != 0:
                    result_dict['envname'] = envinfo_list[0].envname + "(" + envinfo_list[0].ip + ")"
                result_list.append(result_dict)

                # 操作value
                result_dict['approval_option'] = item.stgid  # 上传列表

            # 排序
            for item in result_list:
                if (item.get('stgid') is None):
                    item['stgid'] = '-1'
            result_list_sorted = sorted(result_list, key=itemgetter('stgid'), reverse=True)

            ## 定义两个列表，一个存待审批，另一个存其他审批状态。
            prestatus_list = []
            othstatus_list = []

            for i in range(len(result_list_sorted)):
                if result_list_sorted[i].get("auditstatus") == "待审批":
                    prestatus_list.append(result_list_sorted[i])
                else:
                    othstatus_list.append(result_list_sorted[i])
            prestatus_list.extend(othstatus_list)
            result = my_page(prestatus_list, lim, off)
            return JsonResponse(result, safe=False)

    def post(self, request):
        customerid = request.session.get('id', 'noCid')
        # 审批通过，更改审批状态，打包状态
        if request.POST.get('approval', None):
            stgid = int(request.POST.get('id'))  # int(str)
            stg = Strategy.objects.using('quantWebDB').filter(stgid=stgid)[0]
            stgname = stg.stgname
            stggroup = stg.stggroup
            # 用orm语句，可以直接检索记录进行更新，而不需要循环
            # 实盘审批表
            Liveapproval.objects.using('quantWebDB').filter(stgid=stgid, auditstatus='1').update(
                auditstatus='3',
                packstatus='0',
                audittime=chardate(),
            )

            # 取出qb账号
            stgqb = Liveapproval.objects.using('quantWebDB').filter(stgid=stgid).values_list("remark").first()[0]
            # 运行表
            envs = Environment.objects.using('quantWebDB').filter(type=2)
            for env in envs:
                Liverun.objects.using('quantWebDB').create(
                    stgid=stgid,
                    creattime=chardate(),
                    starttime='',
                    endtime='',
                    envid=env.envid,
                    runstatus='4',
                    runmsg='',
                    isavailable=-1,
                    stoptime='',
                    runpath='',
                )

            customerid = ''
            stgid_list = list(Strategy.objects.using('quantWebDB').filter(stgid=stgid).values_list('customerid'))
            for item in stgid_list:
                customerid = list(item)[0]
            # 用户表
            # 更新或者修改
            if not Customer.objects.using('quantLiveDB').filter(customerid=str(stgid)).exists():
                Customer.objects.using('quantLiveDB').create(
                    customerid=str(stgid),
                    customername='',
                    password='',
                    isactive=1,
                    maxlogined=1000,
                    usertype=8,
                    createtime=chardate(),
                    updatetime=chardate(),
                )

            # 分账户表，customerid == stgid
            if not Customerchannelrel.objects.using('quantLiveDB').filter(customerid=str(stgid)).exists():
                Customerchannelrel.objects.using('quantLiveDB').create(
                    customerid=str(stgid),
                    tdchannelid='Stc_api',
                    mdchannelid='Stc_api',
                    accountid=str(stgid),
                    assetno=str(stgid),
                    combino=str(stgid),
                    tdapitype='b',
                    apiaccountid=stgqb,
                    apiinvestorid=customerid if customerid else "quantapi",  # customerid为空, 值置为quantapi

                )
            # 策略表--rule表
            # ruleid唯一标识一条记录
            if not Rule.objects.using('quantLiveDB').filter(ruleid=stgid).exists():
                Rule.objects.using('quantLiveDB').create(
                    ruleid=stgid,
                    rulepath='',
                    ruleversion=datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
                    rulename=stgname,
                    ruletype=stggroup,
                    configpath='',
                    customerid=str(stgid),
                    isclientloaded=1,
                )

            # 操作日志：仿真审批	审批策略：6p包括两种，审批仿真策略、审批实盘策略。记录审批人、审批策略ID、审批时间、审批结果
            customerid_log = request.session.get('id', 'noCid')
            log_dict = {
                'customerid': customerid_log,
                'modular': '1',
                'optfunction': '4',
                'optinfo': '实盘审批通过，策略ID：%s，审批人：%s，审批时间：%s，审批结果：%s' % (stgid, customerid_log, chardate(), '审批通过'),
                'opttime': chardate(),
            }
            OperationLog.opt_log(log_dict),
            jsonRes = searchs_live(stgid_search="", stgname_search="",
                                   auditstatus_search="", search_type="live_approval")
            return jsonRes
        elif request.POST.get('liveApproval_search', None):
            # 实盘策略审批查询
            # 前端查询条件
            data = json.loads(request.POST.get("data"))
            stgid_search = data.get("lastgid", None)  # if no condition value is str ''
            stgname_search = data.get("lastgname", None)  # str ''
            laauditstatus = data.get("laauditstatus", None)

            jsonRes = searchs_live(stgid_search=stgid_search, stgname_search=stgname_search,
                                   auditstatus_search=laauditstatus, search_type="paper_approval",
                                   customerid=customerid)
            return jsonRes
        elif request.POST.get('livePack_search', None):
            # 实盘策略:打包列表查询
            data = json.loads(request.POST.get("data"))
            stgname_search = data.get("pstgname", None)  # str ''
            packstatus_search = data.get("ppackstatus", None)  # str ''
            jsonRes = searchs_live(stgname_search=stgname_search, packstatus_search=packstatus_search,
                                   type='livePackList', customerid=customerid)
            return jsonRes
        elif request.POST.get('live_search', None):
            # 实盘策略:实盘列表查询
            data = json.loads(request.POST.get("data"))
            stgid_search = data.get("lstgid", None)  # if no condition value is str ''
            stgname_search = data.get("lstgname", None)  # str ''
            stgrunstatus = data.get("lrunstatus", None)
            jsonRes = searchs_live(stgid_search=stgid_search, stgname_search=stgname_search,
                                   stgrunstatus_search=stgrunstatus, type='liveList', customerid=customerid)
            return jsonRes
        # 驳回
        else:
            data = request.POST
            stgid = int(request.POST.get('id'))  # int(str)
            Liveapproval.objects.using('quantWebDB').filter(stgid=stgid, auditstatus='1').update(
                auditstatus='2',
                auditmsg=json.loads(data["data[auditmsg]"])[0],
                audittime=chardate(),
            )

            customerid_log = request.session.get('id', 'noCid')
            log_dict = {
                'customerid': customerid_log,
                'modular': '1',
                'optfunction': '4',
                'optinfo': '实盘审批驳回，策略ID：%s，审批人：%s，审批时间：%s，审批结果：%s' % (stgid, customerid_log, chardate(), '审批驳回'),
                'opttime': chardate(),
            }
            OperationLog.opt_log(log_dict),
            jsonRes = searchs_live(stgid_search="", stgname_search="",
                                   auditstatus_search="", search_type="paper_approval")
            return jsonRes


######业绩分析
## 收益统计
class detail_incomeStatistics(View):
    def __init__(self):
        self.data = None

    # 回测详情中的收益统计的数据获取
    def get(self, request):
        sr = Livesummary
        StgID = request.GET.get("stgid")
        createtime = Strategy.objects.using('quantWebDB').filter(stgid=int(StgID)).values("createtime").first()
        createtime = createtime.get("createtime")[:10]
        if sr.objects.using('quantWebDB').filter(stgid=int(StgID)).count() != 0:
            item = sr.objects.using('quantWebDB').filter(stgid=StgID).values().first()
            obj = {
                "annual_return": str(round(float(item['annualret']) * 100, 3)) + "%",
                "total_return": str(round(float(item['pl']) * 100, 3)) + "%",
                "max_draw_down": str(round(float(item['maxdrawndown']) * 100, 3)) + "%",
                "annual_volatility": str(round(float(item['annualvolatility']), 4)) + "%",
                "sharpe_ratio": str(round(float(item['sharpratio']), 4)) + "%",
                "calmar_ratio": str(round(float(item['calmarratio']), 4)) + "%",
                # "stability_of_time_series": str(round(float(item['stabilityoftimeseries'])), 4),
                # "omega_ratio": str(round(float(item['omegaratio']), 4)),
                "sortino_ratio": str(round(float(item['sortinoratio']), 4)) + "%",
                "start_date": createtime,
                "end_date": item['simenddate'],
            }
            self.data = obj
        return JsonResponse(self.data, safe=False)


## 净值曲线
class detail_cumulativereturns(View):

    def __init__(self):
        self.data = None

    # 回测详情中ECharts净值曲线的数据获取
    def get(self, request):
        stgid = request.GET.get("stgid")
        rc = Livereturn
        retDateList = []
        retDataList = []
        index = 0
        # 先去strategy表中查询stg对应的上传时间，取年月日，然后过滤
        createtime = Strategy.objects.using('quantWebDB').filter(stgid=int(stgid)).values("createtime").first()
        createtime = createtime.get("createtime")[:10]
        if rc.objects.using('quantWebDB').filter(stgid=stgid).values().count() != 0:
            # if rc.find({'strategy_id': backObj['StgID'], 'BacktestID': backObj['BatchID']}).count() != 0:
            returnObj = rc.objects.using('quantWebDB').filter(stgid=stgid).values().first()
            # returnObj = rc.find_one({'strategy_id': backObj['StgID'], 'BacktestID': backObj['BatchID']})
            retDate = str(returnObj['date']).strip("[").rstrip("]").rstrip(',').split(',')
            retData = returnObj['data'].strip('[').rstrip(']').rstrip(',').split(',')
            for key in range(len(retDate)):
                # for item in retDate:
                retdate = retDate[key].replace("\'", '')
                if retdate >= createtime:
                    if retdate == createtime:
                        index = key
                    retDateList.append(retdate)
            for key in range(index, len(retData)):
                retDataList.append(round(float(retData[key].replace("\'", '')), 5))
            self.data = {
                'retDate': retDateList,
                'retData': retDataList
            }
        else:
            self.data = {
                'retDate': retDateList,
                'retData': retDataList
            }
        return JsonResponse(self.data, safe=False)


def AlterQB(request):
    """
    修改qb账号
    """
    stgid = request.POST.get("stgid")
    remark = request.POST.get("qbnum")
    customerid = request.session.get('id', 'noCid')
    try:
        Liveapproval.objects.using('quantWebDB').filter(stgid=stgid).update(remark=remark)
        Customerchannelrel.objects.using('quantLiveDB').filter(customerid=stgid).update(apiaccountid=remark)
        Rule.objects.using('quantLiveDB').filter(ruleid=stgid).update(
            ruleversion=datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        )
        log_dict = {
            'customerid': customerid,
            'modular': '1',
            'optfunction': '14',
            'optinfo': 'QB账号修改成功，策略ID：%s，修改人：%s，操作时间：%s，QB账号：%s' % (stgid, customerid, chardate(), remark),
            'opttime': chardate(),
        }
        OperationLog.opt_log(log_dict),
        jsonRes = searchs_live(stgid_search="", stgname_search="",
                               stgrunstatus_search="", type='liveList', customerid=customerid)
        return jsonRes
    except Exception as e:
        print(e)
        return HttpResponse("")
